# !/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023/9/8 15:29
# @Author  : xinyingjie
# @File    : main-dev.py
# @Description :  速通高速ETC断面高速仿真发车


from __future__ import absolute_import
from __future__ import print_function

import threading
import uuid
import random
import time
import asyncio
import traci.constants as tc
import sumolib
import traci
from util import sumo_utils, kafka_util
from util.kafka_util import real_vehicle_queue
from util.websocketserver1 import WebSocketServer
import logging

# 全局中心点6323.78,31009.31  12320.04,30723.05  5362.89,27538.55  13320.35,27643.33
GLOBAL_POLYGON_CENTER = [(2156.62, 2207.91), (2237.31, 2204.92),
                         (2248.41, 2087.94), (2119.47, 2089.22)]
# 异常标签
unlawfulMap = {"多卡多签": "0101", "车型异常": "0102", "ETC无入口信息": "0103", "疑似屏蔽": "0104", "其他异常": "0104", "无号牌": "0105"}


def main(sumo_cfg_file=None, sumo_net_file=None, gui=True):
    sumo_net_instance = sumolib.net.readNet(sumo_net_file, withInternal=True, withLatestPrograms=True)
    sumo_utils.start_sumo(sumo_cfg_file, False, gui=False)
    # 设置所有车道的最大通行速度
    for id in traci.lane.getIDList():
        traci.lane.setMaxSpeed(id, 100)
    traci.polygon.add('GLOBAL_POLYGON_CENTER', GLOBAL_POLYGON_CENTER, (1, 0, 1))
    traci.polygon.subscribeContext('GLOBAL_POLYGON_CENTER',
                                   tc.CMD_GET_VEHICLE_VARIABLE, 10000,
                                   [tc.VAR_SPEED, tc.VAR_DECEL, tc.VAR_DISTANCE, tc.VAR_TYPE, tc.VAR_POSITION,
                                    tc.VAR_ROAD_ID, tc.VAR_LANE_INDEX, tc.VAR_LANE_ID, tc.VAR_ACCEL, tc.VAR_ANGLE,
                                    tc.VAR_LANE_ID, tc.VAR_ACCELERATION, tc.VAR_LANE_INDEX,
                                    tc.TRAFFICLIGHT_TYPE_STATIC])
    traci.simulation.subscribe([tc.VAR_ARRIVED_VEHICLES_NUMBER,
                                tc.VAR_ARRIVED_VEHICLES_IDS,
                                tc.VAR_DEPARTED_VEHICLES_NUMBER,
                                tc.VAR_DEPARTED_VEHICLES_IDS,
                                tc.VAR_COLLIDING_VEHICLES_NUMBER,
                                tc.VAR_COLLIDING_VEHICLES_IDS])
    # 获取虚拟设备状态kafka数据
    vir_thread = threading.Thread(target=kafka_util.receive_message_of_ETC_vehicle)
    vir_thread.start()
    ws_server = WebSocketServer()
    ws_server.start()

    EdgeID, Pos, LaneIndex = traci.simulation.convertRoad(116.1922105774,39.7909376219, True)
    EdgeID1, Pos1, LaneIndex1 = traci.simulation.convertRoad(116.1921713501215, 39.7909468963, True)
    EdgeID2, Pos2, LaneIndex2 = traci.simulation.convertRoad(116.192129440, 39.79095024537, True)
    routeID = str(uuid.uuid1())
    traci.route.add(routeID, [EdgeID])
    routeID1 = str(uuid.uuid1())
    traci.route.add(routeID1, [EdgeID1])
    routeID2 = str(uuid.uuid1())
    traci.route.add(routeID2, [EdgeID2])

    # print(EdgeID, Pos, LaneIndex)
    # print(EdgeID1, Pos1, LaneIndex1)
    # print(EdgeID2, Pos2, LaneIndex2)

    posDict = {"1": {"pos": Pos, "route": routeID}, "2": {"pos": Pos1, "route": routeID1},
               "3": {"pos": Pos2, "route": routeID2}}

    # f = open("data//data0908v1.json", encoding='utf-8')
    try:
        loop = asyncio.get_event_loop()
        while (True):
            try:
                if not real_vehicle_queue.empty():
                    vehiclePicInfo = real_vehicle_queue.get(block=False)

                    # if line:
                    #     vehiclePicInfo = json.loads(line)
                    unlawfulMold = vehiclePicInfo["unlawfulMold"]
                    if (vehiclePicInfo['identifyType'] < 4):
                        typeid = '1'
                    elif (10 < vehiclePicInfo['identifyType'] < 17):
                        typeid = '3'
                    else:
                        typeid = '15'
                    # 如果车辆数据里没有车道字段，车辆的发车点随机选择
                    if ('headLaneNum' not in vehiclePicInfo.keys()):
                        logging.info("车辆数据里没有车道字段")
                        # 如果车辆数据里面没有车牌号字段，车辆的车辆id为车辆的recordId
                        if ('licenseCode' not in vehiclePicInfo.keys()):
                            logging.info("车辆数据里没有车牌号字段")
                            if len(unlawfulMold) > 0:
                                traci.vehicle.add(vehID=" " + "_" + str(vehiclePicInfo['recordId']) + "_" + unlawfulMold,
                                                  routeID=routeID, typeID=typeid, depart='0',
                                                  departLane=str(random.randint(0, 2)),
                                                  departSpeed=str(vehiclePicInfo['vehicleSpeed'] / 3.6))
                            else:
                                traci.vehicle.add(vehID=" " + "_" + str(vehiclePicInfo['recordId']),
                                                  routeID=routeID, typeID=typeid, depart='0',
                                                  departLane=str(random.randint(0, 2)),
                                                  departSpeed=str(vehiclePicInfo['vehicleSpeed'] / 3.6))

                        else:
                            if len(unlawfulMold) > 0:
                                traci.vehicle.add(vehID=vehiclePicInfo['licenseCode'] + "_" + str(
                                    vehiclePicInfo['recordId']) + "_" + unlawfulMold,
                                                  routeID=routeID, typeID=typeid,
                                                  depart='0', departLane=str(random.randint(0, 2)),
                                                  departSpeed=str(vehiclePicInfo['vehicleSpeed'] / 3.6))
                            else:
                                traci.vehicle.add(
                                    vehID=vehiclePicInfo['licenseCode'] + "_" + str(vehiclePicInfo['recordId']),
                                    routeID=routeID, typeID=typeid,
                                    depart='0', departLane=str(random.randint(0, 2)),
                                    departSpeed=str(vehiclePicInfo['vehicleSpeed'] / 3.6))

                    else:
                        if len(unlawfulMold) > 0:
                            traci.vehicle.add(
                                vehID=str(vehiclePicInfo['licenseCode'].encode('UTF-8')) + "_" + str(
                                    vehiclePicInfo['recordId']) + "_" + unlawfulMold,
                                routeID=posDict[vehiclePicInfo['headLaneNum']]["route"],
                                typeID=typeid, depart='0', departPos=posDict[vehiclePicInfo['headLaneNum']]["pos"],
                                departLane=str(int(vehiclePicInfo['headLaneNum']) - 1),
                                departSpeed=str(vehiclePicInfo['vehicleSpeed'] / 3.6))
                        else:
                            traci.vehicle.add(
                                vehID=str(vehiclePicInfo['licenseCode'].encode('UTF-8')) + "_" + str(
                                    vehiclePicInfo['recordId']),
                                routeID=posDict[vehiclePicInfo['headLaneNum']]["route"],
                                typeID=typeid, depart='0', departPos=posDict[vehiclePicInfo['headLaneNum']]["pos"],
                                departLane=str(int(vehiclePicInfo['headLaneNum']) - 1),
                                departSpeed=str(vehiclePicInfo['vehicleSpeed'] / 3.6))

                global_vehicles = traci.polygon.getContextSubscriptionResults('GLOBAL_POLYGON_CENTER')
                car_list = list()
                # print(len(global_vehicles))
                for vehicle_id, veh_info in dict(global_vehicles).items():
                    if True:
                        pos = veh_info[tc.VAR_POSITION]
                        longitude, latitude = sumo_utils.xyConversionlatAndLon(sumo_net_instance, pos)
                        speed = veh_info[tc.VAR_SPEED]
                        vehicle_type = veh_info[tc.VAR_TYPE]
                        info = vehicle_id.split("_")
                        unlawfulMold = ""
                        if len(info) == 3:
                            unlawfulMold = info[2]
                        vId = info[1]
                        licenseCode = info[0]
                        car = {"id": vId, "vehicleType": vehicle_type, "longitude": longitude,
                               "latitude": latitude,
                               "courseAngle": veh_info[tc.VAR_ANGLE], "acceleration": veh_info[tc.VAR_ACCELERATION],
                               "speed": round(speed * 3.6, 2), "laneNum": veh_info[tc.VAR_LANE_INDEX],
                               "licenseode": eval(licenseCode).decode('utf-8'),
                               "unlawfulMold": unlawfulMold,
                               "unlawfulCode": unlawfulMap[unlawfulMold] if unlawfulMold in unlawfulMap.keys() else "",
                               }

                        car_list.append(car)

                result = {"e1FrameParticipant": car_list, "participantNum": len(car_list),
                          "timeStamp": str(time.time()),
                          "globalTimeStamp": str(time.time())}

                loop.run_until_complete(ws_server.broadcast(str(result).replace("'", '"')))
                # websocketserver.test("1111")
                traci.simulationStep()
                time.sleep(0.05)
            except Exception as e:
                logging.exception(str(e))
                continue

    except Exception as e:
        logging.exception(str(e))


if __name__ == "__main__":
    sumo_net_file = "./config/0815-v1.net.xml"  # 路网文件
    sumo_cfg_file = "./config/longshan.sumocfg"  # 路网文件
    main(sumo_cfg_file=sumo_cfg_file, sumo_net_file=sumo_net_file)
